#pragma once
#include <graphics.h>
#include <conio.h>

#define SCREEN_WIDTH 768
#define SCREEN_HEIGHT 960
#define MAP_HEIGHT 9
#define MAP_WIDTH 12
#define RATIO 61
#define START_X 100
#define START_Y 100
#define KEY_UP 72
#define KEY_DOWN 80
#define KEY_RIGHT 77
#define KEY_LEFT 75
#define KEY_QUIT 0X1B//esc
#define isVald(pos) pos.x >= 0 && pos.x<MAP_HEIGHT&&pos.y >= 0 && pos.y<MAP_WIDTH
IMAGE bg_img;

typedef enum PROPS {
	WALL,
	FLOOR,
	BOX_DES,
	MAN,
	BOX,
	HIT,
	HIT1,
	ALL
}PROPS;

enum DIR {
	UP,
	DOWN,
	RIGHT,
	LEFT
};


typedef struct LOC {
	int x;
	int y;
}location;
location man;
location next_man;
location next_next_man;
IMAGE image[ALL];




struct MAP
{
	int map[MAP_HEIGHT][MAP_WIDTH];
	struct MAP* next;

};
MAP* p;
MAP* m;

int map1[MAP_HEIGHT][MAP_WIDTH] = {
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
	{ 0, 1, 4, 1, 0, 2, 1, 0, 2, 1, 0, 0 },
	{ 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0 },
	{ 0, 1, 0, 2, 0, 1, 1, 4, 1, 1, 1, 0 },
	{ 0, 1, 1, 1, 0, 3, 1, 1, 1, 4, 1, 0 },
	{ 0, 1, 2, 1, 1, 4, 1, 1, 1, 1, 1, 0 },
	{ 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
};
//int map2[MAP_HEIGHT][MAP_WIDTH] = {
//	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
//	{ 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
//	{ 0, 1, 4, 1, 0, 2, 1, 0, 2, 1, 0, 0 },
//	{ 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0 },
//	{ 0, 1, 0, 2, 0, 1, 1, 4, 1, 1, 1, 0 },
//	{ 0, 1, 1, 1, 0, 3, 1, 1, 1, 4, 1, 0 },
//	{ 0, 1, 2, 1, 1, 4, 1, 1, 1, 1, 1, 0 },
//	{ 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0 },
//	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
//};
//int map3[MAP_HEIGHT][MAP_WIDTH] = {
//	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
//	{ 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
//	{ 0, 1, 4, 1, 0, 2, 1, 0, 2, 1, 0, 0 },
//	{ 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0 },
//	{ 0, 1, 0, 2, 0, 1, 1, 4, 1, 1, 1, 0 },
//	{ 0, 1, 1, 1, 0, 3, 1, 1, 1, 4, 1, 0 },
//	{ 0, 1, 2, 1, 1, 4, 1, 1, 1, 1, 1, 0 },
//	{ 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0 },
//	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
//};
int map2[MAP_HEIGHT][MAP_WIDTH] = {
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 2, 2, 2, 2, 1, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 2, 2, 2, 4, 0, 0, 0, 0 },
	{ 0, 0, 1, 1, 4, 0, 4, 1, 4, 1, 0, 0 },
	{ 0, 0, 1, 4, 4, 1, 1, 0, 4, 1, 0, 0 },
	{ 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0 },
	{ 0, 0, 0, 0, 0, 3, 1, 1, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
};
int map3[MAP_HEIGHT][MAP_WIDTH] = {
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 2, 1, 2, 2, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 2, 1, 4, 2, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 1, 1, 4, 0, 0, 0, 0 },
	{ 0, 0, 0, 1, 4, 1, 1, 4, 1, 0, 0, 0 },
	{ 0, 0, 0, 1, 0, 4, 0, 0, 1, 0, 0, 0 },
	{ 0, 0, 0, 1, 1, 1, 3, 1, 1, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
};
void changeMap(location *next, PROPS x, int mapt[MAP_HEIGHT][MAP_WIDTH]) {
	mapt[next->x][next->y] = x;
	putimage(START_Y + RATIO*next->y, START_X + RATIO*next->x, &image[x]);
}
void changeMAN(location *next, int mapt[MAP_HEIGHT][MAP_WIDTH]) {
	if (mapt[next->x][next->y] == HIT1) {
		changeMap(next, BOX_DES,mapt);
	}
	else {
		changeMap(next, FLOOR,mapt);
	}
}
void gameControl(enum DIR direction,int mapt[MAP_HEIGHT][MAP_WIDTH]) {
	next_man = man;
	next_next_man = man;
	if (direction == UP) {
		next_man.x--;
		next_next_man.x -= 2;
	}
	else if (direction == DOWN) {
		next_man.x++;
		next_next_man.x += 2;
	}
	else if (direction == RIGHT) {
		next_man.y++;
		next_next_man.y += 2;
	}
	else if (direction == LEFT) {
		next_man.y--;
		next_next_man.y -= 2;
	}
	if (isVald(next_man) && mapt[next_man.x][next_man.y] == FLOOR) {
		changeMap(&next_man, MAN,mapt);
		changeMAN(&man, mapt);
		man = next_man;
	}
	else if (isVald(next_man) && mapt[next_man.x][next_man.y] == BOX_DES) {
		changeMap(&next_man, HIT1,mapt);
		changeMAN(&man,mapt);
		man = next_man;
	}
	else if (isVald(next_man) && isVald(next_next_man) && mapt[next_man.x][next_man.y] == BOX) {
		if (mapt[next_next_man.x][next_next_man.y] == FLOOR) {
			changeMap(&next_next_man, BOX, mapt);
			changeMap(&next_man, MAN, mapt);
			changeMAN(&man, mapt);
			man = next_man;
		}
		else if (mapt[next_next_man.x][next_next_man.y] == BOX_DES) {
			changeMap(&next_next_man, HIT, mapt);
			changeMap(&next_man, MAN, mapt);
			changeMAN(&man, mapt);
			man = next_man;


		}
	}
		else if (isVald(next_man) &&isVald(next_next_man)&&  mapt[next_man.x][next_man.y] == HIT) {
			if ( mapt[next_next_man.x][next_next_man.y] == FLOOR ) {
				changeMap(&next_next_man, BOX, mapt);
				changeMap(&next_man, HIT1, mapt);
				changeMAN(&man, mapt);
				man = next_man;
			}
			else if ( mapt[next_next_man.x][next_next_man.y] == BOX_DES) {
				changeMap(&next_next_man, HIT, mapt);
				changeMap(&next_man, HIT1, mapt);
				changeMAN(&man, mapt);
				man = next_man;
			}
		}
	
}
bool isOver(int mapt[MAP_HEIGHT][MAP_WIDTH]) {
	for (int i = 0; i < MAP_HEIGHT; i++) {
		for (int j = 0; j < MAP_WIDTH; j++) {
			if (mapt[i][j] == BOX_DES||mapt[i][j] == HIT1) {
				return false;
			}
		}
	}
	return true;
}